#include "commerrno.h"
#include "CBattleRole.h"
#include "CBattleRules.h"
#include "CBattleVideo.h"
#include "CBattleInf.h"
#include "../mainctrl.h"
#include "../status/CStatusMgr.h"

/************************************************************************/
/*                    CBattleRole                                       */
/************************************************************************/
int CBattleRole::InitBattleRole(int iID, CBattleRoleData& stBattleRoleDate)
{
    int iRet = 0;

    if (iID < 0 || iID >= MAX_BATTLE_ROLES)
    {
        return ERROR_BATTLE_ROLE_ID;
    }

    iRet = stBattleRoleDate.CheckData();
    CT_RETURN(iRet);

    //初始值
    _stBuffList.Clear();
    _stSkillList.Clear();
    _chCourageStat = COURAGE_STAT_NORMAL;
    _chAngerStat = ANGER_STAT_NORMAL;
    _iHasDoNormalAtkCount = 0;

    //赋值
    _stRoleBase = stBattleRoleDate;

    _iID = iID;
    //_stRoleBase._iBattleID = iID;//这里暂时不要赋值
    
    //此站位强制绑定为左向战斗地图正向增长(即此站位就是左向战斗地图的站位)
    _iGridPos = _stRoleBase._bIsLeft
                   ? stBattleRoleDate._iGridPos
                   : MAX_BATTLE_GRIDS - 1 - stBattleRoleDate._iGridPos;

    return 0;
}

void CBattleRole::DumpRoleInfo(bool bIsTurnBegin)
{
    CT_BATTLE(("%-18s = %d", "战场ID", _iID));
    CT_BATTLE(("%-18s = %d", "当前站位", _iGridPos));
    CT_BATTLE(("%-18s = %d", "勇气状态", _chCourageStat));
    CT_BATTLE(("%-18s = %d", "怒气状态", _chAngerStat));
    CT_BATTLE(("%-18s = %d", "普通攻击次数", _iHasDoNormalAtkCount));

    _stRoleBase.DumpRoleData(_stBattleAttr,_stTurnMainAttr,_stTurnMinorAttr,
            bIsTurnBegin);

    if (bIsTurnBegin)
    {
        DumpBattleBuffList();
    }
}

int CBattleRole::RoleAttrChg(int iAttrBefore)
{
    int iRet = 0;
    if (GetHP() != iAttrBefore)
    {
        //状态处理 STATUS_TRIGGER_GET_HURT //受伤掉血时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_GET_HURT, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_GET_HURT));
        }

        //状态处理 STATUS_TRIGGER_SELF_ATTR_CHG //自身属性改变时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_SELF_ATTR_CHG,
                CSkillEffect::SKILL_SUB_STAT_HP, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_ATTR_CHG));
        }

        //状态处理 STATUS_TRIGGER_SELF_ATTR_LIMIT //自身属性临界时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_SELF_ATTR_LIMIT,
                CSkillEffect::SKILL_SUB_STAT_HP, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_ATTR_LIMIT));
        }
    }

    return 0;
}

//注意：接口调用ChgBlood 并输出血量修改录像 如果死亡输出死亡录像
int CBattleRole::ModRoleHP(int iChgValue, int iAttackID)
{
    if (0 == iChgValue) {return 0;}

    int iHPBefore = GetHP();

    int iRet = ChgBlood(iChgValue);
    CT_RETURN(iRet);

    BATTLE_INF->_pstVideo->ModPlayerHP(_iID, iChgValue);

    RoleAttrChg(iHPBefore);

    int iRoleID = 0;

    if (iChgValue < 0 && HasDead())
    {
        BATTLE_INF->_pstVideo->RoleAngerStat(_iID, BATTLE_VIDEO_ANGER_DEL);
        RoleDelAllBuff();

        BATTLE_INF->_pstRules->SetNowKiller(iAttackID);

        CT_BATTLE(("角色(%d)因血量为0而死亡", _iID));
        BATTLE_INF->_pstVideo->RoleDead(_iID);

        //状态处理 STATUS_TRIGGER_SELF_DIE //自己死亡时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
            *this, CStatusMgr::STATUS_TRIGGER_SELF_DIE, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_DIE));
        }

        //状态处理 STATUS_TRIGGER_SELF_DIE_ALL_DIE
        //自己死亡时触发 且是本方最后一个死亡 +
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
            *this, CStatusMgr::STATUS_TRIGGER_SELF_DIE_ALL_DIE, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_DIE_ALL_DIE));
        }

        CMapSide& stMapSide = BATTLE_INF->_pstMap->GetMapSide(IsLeft());
        MAP_GRID_MULTI stMapGridMulti;
        stMapSide.GetDistanceRoles(0, stMapSide.GetLeftFrontTo(), stMapGridMulti);
        for (int i = 0; i < stMapGridMulti.Size(); ++i)
        {
            iRoleID = stMapGridMulti[i].GetRoleID();
            if (!BATTLE_INF->_pstRoles->IsValidRoleID(iRoleID))
            {
                continue;
            }
            CBattleRole& stTeamRole = BATTLE_INF->_pstRoles->GetRole(iRoleID);

            //状态处理 STATUS_TRIGGER_TEAMMATE_DIE //队友死亡时触发
            iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                    stTeamRole, CStatusMgr::STATUS_TRIGGER_TEAMMATE_DIE, 0);
            if (iRet)
            {
                CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                            stTeamRole.GetRoleID(),
                            CStatusMgr::STATUS_TRIGGER_TEAMMATE_DIE));
            }
        }
    }

    return 0;
}

//注意：最底层血量修改接口 如果死亡需重建战斗地图边界
int CBattleRole::ChgBlood(int& iChgBlood)
{
    if (0 == iChgBlood) {return 0;}

    int iRet = 0;

    int iHPBefore = GetHP();

    if (iChgBlood > 0)
    {
        _stRoleBase._iHP = CT_MIN(_stRoleBase._iHP + iChgBlood, _stRoleBase._iHPMax);
        CT_BATTLE(("角色(%d)血量增加(%d)血量剩余(%d)", _iID, iChgBlood, GetHP()));
    }
    else
    {
        if (HasDead())//避免死亡后复活的逻辑造成无限递归
        {
            return 0;
        }

        //增加护盾的检查
        _stBuffList.DealShieldBuff(_iID, iChgBlood);

        _stRoleBase._iHP = CT_MAX(_stRoleBase._iHP + iChgBlood, 0);
        CT_BATTLE(("角色(%d)血量减少(%d)血量剩余(%d)", _iID, iHPBefore - GetHP(), GetHP()));

        if (HasDead())
        {
            //状态处理 STATUS_TRIGGER_SELF_DIE_OR_LIFE //自己死亡时触发 有可能豁免+
            CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(*this,
                CStatusMgr::STATUS_TRIGGER_SELF_DIE_OR_LIFE, 0);
        }

        if (HasDead())
        {
            iRet = BATTLE_INF->_pstMap->ReCalcBorder();
            if (iRet) {CT_WARNING(("Role die but recalc border fail(%d)!",iRet));}

            BATTLE_INF->_pstVideo->RoleAngerStat(_iID, BATTLE_VIDEO_ANGER_DEL);
            RoleDelAllBuff();
        }
    }

    return iRet;
}

int CBattleRole::CastSkill(CSkill& stSkill)
{
    int iRet = 0;
    int64 i64ValueTmp = INT64_1 * GetHP() * stSkill.GetUseHPPercent();
    i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;

    int iHPUse = (int)(i64ValueTmp);
    if (iHPUse < 0)
    {
        iHPUse = 0 - iHPUse;
    }

    int iAngerBefore = GetAnger();
    int iHPBefore = GetHP();

    if (stSkill.GetUseAnger() > iAngerBefore || iHPUse > iHPBefore)
    {
        return ERROR_NOT_ENOUGH_ANGER;
    }

    if (stSkill.IsMagicSkill())
    {
        _iUseAnger = iAngerBefore;
        ModAnger(0 - iAngerBefore);//怒气全部扣除 且在接口内部输出录像
    }

    if (iHPUse > 0)
    {
        iRet = ModRoleHP(0 - iHPUse, _iID);
        CT_RETURN(iRet);
    }

    CT_BATTLE(("技能消耗怒气(%d)血量(千分之%d)；消耗后剩余怒气(%d)血量(%d)", 
                stSkill.GetUseAnger(), stSkill.GetUseHPPercent(), GetAnger(), GetHP()));

    return 0;
}

bool CBattleRole::IsSwim() 
{
    return _stBuffList.IsSwim();
}

bool CBattleRole::IsStick() 
{
    return _stBuffList.IsStick();
}

int CBattleRole::AddBuff(CSkillEffect& stSkillEffect, int iSrcType, int iSrcID)
{
    return _stBuffList.AddOneBuff(_iID, stSkillEffect, iSrcType, iSrcID);
}

void CBattleRole::RoleAddBuffVideo(unsigned int uiEffectID, int iSrcType,
        int iSrcID, int iTurn, int iAddNum)
{
    _stBuffList.RoleAddBuffVideo(_iID, uiEffectID, iSrcType, iSrcID, iTurn,
        iAddNum);
}

bool CBattleRole::InDefinitBuff(unsigned char ucStatType,
        unsigned char ucSubType)
{
    return _stBuffList.InDefinitBuff(ucStatType, ucSubType);
}

bool CBattleRole::InDefinitSubBuff(unsigned char ucStatType,
        unsigned char ucSubType, int iData)
{
    return _stBuffList.InDefinitSubBuff(ucStatType, ucSubType, iData);
}

int CBattleRole::DelBuffByStatType(unsigned char ucStatType)
{
    return _stBuffList.DelBuffByStatType(_iID, ucStatType);
}

int CBattleRole::DelBuffBySubType(unsigned char ucStatType,
        unsigned char ucSubType)
{
    return _stBuffList.DelBuffBySubType(_iID, ucStatType, ucSubType);
}

void CBattleRole::RoleDelAllBuff()
{
    _stBuffList.DelAllBuff(_iID);
}

int CBattleRole::CalcBuffBeforeTurn(bool& bTurnOver)
{
    unsigned char ucStatType = 0;
    unsigned char ucSubType = 0;
    int iChgValue = 0;

    _stBuffList.NewTurn(_iID);

    CBattleReviseUnit stReviseUnit;

    for (int i = 0; i < _stBuffList.GetBuffSize(); ++i)
    {
        if (HasDead())
        {
            bTurnOver = true;
            return 0;
        }

        CBattleBuff& stBattleBuff = _stBuffList.GetBattleBuff(i);
        
        ucStatType = stBattleBuff.GetStatType();
        ucSubType = stBattleBuff.GetSubType();
        iChgValue = 0;

        BATTLE_INF->_pstRules->SkillPreEffectDataCalc(iChgValue, GetHPMax(),
            stBattleBuff.GetSkillEffect(), stBattleBuff.GetLastSize());

        if (CSkillEffect::SKILL_STAT_BUFF_HOT == ucStatType ||
            CSkillEffect::SKILL_STAT_BUFF_DOT == ucStatType)
        {
            if (0 != iChgValue)
            {
                ModRoleHP(iChgValue, stBattleBuff.GetSrcRoleID());
            }
        }
        else if (ucStatType == CSkillEffect::SKILL_STAT_BUFF_1 ||
                 ucStatType == CSkillEffect::SKILL_STAT_DEBUFF_1 ||
                 ucStatType == CSkillEffect::SKILL_STAT_BUFF_2 ||
                 ucStatType == CSkillEffect::SKILL_STAT_DEBUFF_2 ||
                 ucStatType == CSkillEffect::SKILL_STAT_BUFF_3 ||
                 ucStatType == CSkillEffect::SKILL_STAT_DEBUFF_3 ||
                 ucStatType == CSkillEffect::SKILL_STAT_BUFF_TREASURE ||
                 ucStatType == CSkillEffect::SKILL_STAT_BUFF_MOUNT)
        {
            if (CSkillEffect::SKILL_SUB_STAT_HP == ucSubType)
            {
                if (0 != iChgValue)
                {
                    //设置当前攻击者ID
                    BATTLE_INF->_pstRules->SetNowAttack(
                        stBattleBuff.GetSrcRoleID());
                    ModRoleHP(iChgValue, stBattleBuff.GetSrcRoleID());
                }
            }
            else if (CSkillEffect::SKILL_SUB_STAT_COURAGE == ucSubType)
            {
                if (0 != iChgValue)
                {
                    ModCourage(iChgValue);
                    if (iChgValue < 0 && GetCourage() <= 0 &&
                            !IsHaveToTurnWait() && !IsRecvCourageAndAct())
                    {
                        //撤退逻辑(或者说向后移动)需要地图格支持 这里先不执行撤退
                        SetFallBackRightNow();
                    }
                    if (iChgValue > 0 && IsFallBackRightNow() &&
                            GetCourage() > 0)
                    {
                        SetCourageNormal();
                    }
                }
            }
            else if (CSkillEffect::SKILL_SUB_STAT_ANGER == ucSubType)
            {
                if (0 != iChgValue)
                {
                    ModAnger(iChgValue);
                }
            }
            else if (CSkillEffect::SKILL_SUB_STAT_REVISE_VAL == ucSubType)
            {
                stReviseUnit.Clear();
                stReviseUnit.SetAddNum(1);
                stReviseUnit.SetEffectID(stBattleBuff.GetID());
                BATTLE_INF->_pstRules->AddReviseUnit(stReviseUnit);
            }
        }
        else if (CSkillEffect::SKILL_STAT_SWIM == ucStatType)
        {
            bTurnOver = true;
            BATTLE_INF->_pstVideo->IsSwimTurnEnd(_iID);
        }
    }

    return 0;
}

int CBattleRole::CalcBuffAddAttr(CPlayerAttr& stPlayerAttr)
{
    //首先初始化 每次先清空
    stPlayerAttr.Clear();

    unsigned char ucStatType = 0;
    unsigned char ucSubType = 0;
    int iChgValue = 0;

    CT_BATTLE(("计算角色(%d)Buff效果修正属性:数量(%d)",
               _iID,_stBuffList.GetBuffSize()));

    for (int i = 0; i < _stBuffList.GetBuffSize(); ++i)
    {
        CBattleBuff& stBattleBuff = _stBuffList.GetBattleBuff(i);

        ucStatType = stBattleBuff.GetStatType();
        ucSubType = stBattleBuff.GetSubType();
        iChgValue = 0;

        if (ucStatType == CSkillEffect::SKILL_STAT_BUFF_1 ||
            ucStatType == CSkillEffect::SKILL_STAT_DEBUFF_1 ||
            ucStatType == CSkillEffect::SKILL_STAT_BUFF_2 ||
            ucStatType == CSkillEffect::SKILL_STAT_DEBUFF_2 ||
            ucStatType == CSkillEffect::SKILL_STAT_BUFF_3 ||
            ucStatType == CSkillEffect::SKILL_STAT_DEBUFF_3 ||
            ucStatType == CSkillEffect::SKILL_STAT_BUFF_TREASURE ||
            ucStatType == CSkillEffect::SKILL_STAT_BUFF_MOUNT)
        {
            iChgValue = stPlayerAttr.GetAttr(ucSubType);

            stBattleBuff.DumpBattleBuff();

            BATTLE_INF->_pstRules->SkillPreEffectDataCalc(iChgValue,
                GetTypeAttr(ucSubType), stBattleBuff.GetSkillEffect(),
                stBattleBuff.GetLastSize());

            stPlayerAttr.SetAttr(ucSubType, iChgValue);
        }
    }

    return 0;
}

void CBattleRole::SetRoleTurnWait() 
{
    _chCourageStat = COURAGE_STAT_TURN_WAIT;
    BATTLE_INF->_pstVideo->RoleCourageStat(_iID, BATTLE_VIDEO_COURAGE_ADD);
}

int CBattleRole::RecvCourageAndAct() 
{
    BATTLE_INF->_pstVideo->RoleCourageStat(_iID, BATTLE_VIDEO_COURAGE_DEL);
    SetCourageNormal();
    return ModCourage(_stRoleBase._iCourageMax);
}

int CBattleRole::ModCourage(int iValue)
{
    if (iValue == 0)
    {
        return 0;
    }
    int iRet = 0;
    int iCourageBefore = GetCourage();
    if (iValue > 0)
    {
        _stRoleBase._iCourage = CT_MIN(iValue + _stRoleBase._iCourage, _stRoleBase._iCourageMax);
    }
    else
    {
        _stRoleBase._iCourage = CT_MAX(iValue + _stRoleBase._iCourage, 0);
    }
    CT_BATTLE(("角色(%d)修改勇气(%d)剩余勇气(%d)", _iID, iValue, _stRoleBase._iCourage));
    BATTLE_INF->_pstVideo->ModCourage(_iID, GetCourage() - iCourageBefore);

    if (GetCourage() < iCourageBefore)
    {
        //状态处理 STATUS_TRIGGER_SELF_ATTR_CHG //自身属性改变时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_SELF_ATTR_CHG,
                CSkillEffect::SKILL_SUB_STAT_COURAGE, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_ATTR_CHG));
        }

        //状态处理 STATUS_TRIGGER_SELF_ATTR_LIMIT //自身属性临界时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_SELF_ATTR_LIMIT,
                CSkillEffect::SKILL_SUB_STAT_COURAGE, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_ATTR_LIMIT));
        }
    }

    return 0;
}

int CBattleRole::ModAnger(int iValue)
{
    if (0 == iValue)
    {
        return 0;
    }

    if (!IsAngerOpen())
    {
        return 0;
    }

    int iRet = 0;
    int iAngerBefore = GetAnger();

    if (iValue > 0)
    {
        _stRoleBase._iAnger = CT_MIN(iValue + _stRoleBase._iAnger, MAX_ROLE_ANGER_ADD);
    }
    else
    {
        _stRoleBase._iAnger = CT_MAX(iValue + _stRoleBase._iAnger, 0);
    }

    CT_BATTLE(("角色(%d)修改怒气(%d)剩余怒气(%d)", _iID, iValue, _stRoleBase._iAnger));
    BATTLE_INF->_pstVideo->ModAnger(_iID, GetAnger() - iAngerBefore);

    if (iValue > 0 && GetAnger() >= GetAngerMax() && !IsAngerFull())
    {
        SetAngerFull();
        BATTLE_INF->_pstVideo->RoleAngerStat(_iID, BATTLE_VIDEO_ANGER_ADD);
    }
    else if(iValue < 0 && GetAnger() < GetAngerMax() && IsAngerFull())
    {
        SetAngerNormal();
        BATTLE_INF->_pstVideo->RoleAngerStat(_iID, BATTLE_VIDEO_ANGER_DEL);
    }

    if (GetAnger() < iAngerBefore)
    {
        //状态处理 STATUS_TRIGGER_SELF_ATTR_CHG //自身属性改变时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_SELF_ATTR_CHG,
                CSkillEffect::SKILL_SUB_STAT_ANGER, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_ATTR_CHG));
        }

        //状态处理 STATUS_TRIGGER_SELF_ATTR_LIMIT //自身属性临界时触发
        iRet = CMainCtrl::m_pstMain->m_stStatusMgr.StatusSkillAffect(
                *this, CStatusMgr::STATUS_TRIGGER_SELF_ATTR_LIMIT,
                CSkillEffect::SKILL_SUB_STAT_ANGER, 0);
        if (iRet)
        {
            CT_WARNING(("battle role(%d) trigger way(%d) status error(%d)",
                        GetRoleID(),CStatusMgr::STATUS_TRIGGER_SELF_ATTR_LIMIT));
        }
    }

    return 0;
}

/************************************************************************/
/*                       CBattleRoles                                   */
/************************************************************************/

int CBattleRoles::AddBattleRole(CBattleRoleData& stBattleRoleData)
{
    stBattleRoleData._iBattleID = -1;

    CBattleRole stBattleRole;
    int iRet = stBattleRole.InitBattleRole(_astRoles.Size(), stBattleRoleData);
    CT_RETURN(iRet);

    iRet = _astRoles.AddOneItem(stBattleRole);
    if (iRet < 0)
    {
        CT_ERROR((""));
        return -1;
    }
    stBattleRoleData._iBattleID = iRet;

    return 0;
}

void CBattleRoles::DumpRolesInfo()
{
    CT_BATTLE(("角色总数(%d)", _astRoles.Size()));
    for(int i = 0; i < _astRoles.Size(); ++i)
    {
        CT_BATTLE(("第(%d)个角色的属性及技能信息", i+1));
        _astRoles[i].DumpRoleInfo(false);
    }
}

int CBattleRoles::InitBattleRoundCtrl()
{
    int iRet = 0;
    for (int i = 0; i < _astRoles.Size(); ++i)
    {
        iRet = BATTLE_INF->_pstRoundCtrl->InitAddRole(_astRoles[i]);
        CT_RETURN(iRet);
    }

    return 0;
}

int CBattleRoles::GetTotalTurnOrder(bool& bIsLeftFirst)
{
    int iLeft = 0;
    int iRight = 0;
    for (int i = 0; i < _astRoles.Size(); ++i)
    {
        if (_astRoles[i].GetTurnOrderValue() > 0) 
        {
            if (_astRoles[i].IsLeft())
            {
                iLeft += _astRoles[i].GetTurnOrderValue();
            }
            else
            {
                iRight += _astRoles[i].GetTurnOrderValue();
            }
        }
    }

    bIsLeftFirst = false;
    if (iLeft >= iRight)
    {
        bIsLeftFirst = true;
    }

    return 0;
}

void CBattleRoles::CalcBattleTotalHP(bool bIsLeft, int& iTotalNow,
        int& iTotalMax)
{
    iTotalNow = 0;
    iTotalMax = 0;

    for (int i = 0; i < _astRoles.Size(); ++i)
    {
        if (_astRoles[i].IsLeft() == bIsLeft)
        {
            iTotalNow += _astRoles[i].GetHP();
            iTotalMax += _astRoles[i].GetHPMax();
        }
    }
}

int CBattleRoles::GetRole(int iRoleID, CBattleRole& stBattleRole)
{
    if (iRoleID < 0 || iRoleID >= _astRoles.Size())
    {
        return ERROR_BATTLE_GRID_ID;
    }

    stBattleRole = _astRoles[iRoleID];
    return 0;
}

CBattleRole& CBattleRoles::GetRole(int iRoleID)
{
    return _astRoles[iRoleID];
}

CBattleRoleData& CBattleRoles::GetRoleBase(int iRoleID)
{
    return _astRoles[iRoleID].GetRoleBase();
}

int CBattleRoles::GetLivingRoleCount(bool bIsLeft)
{
    int iCount = 0;

    for (int i = 0; i < _astRoles.Size(); ++i)
    {
        if (_astRoles[i].IsLeft() == bIsLeft 
            && !_astRoles[i].HasDead())
        {
            iCount++;
        }
    }

    return iCount;
}

